package controller

import (
	"fmt"
	"net/http"
	"time"

	"github.com/labstack/echo"

	"gopkg.in/mgo.v2/bson"

	"m-project-admin/app/entity"
	"m-project-admin/app/manager"
	"m-project-admin/app/model"
	"m-project-admin/app/utils"
	"strings"
)

// AddPremission
func AddPremission(c echo.Context) error {
	loginAdminInfo := manager.GetLoginAdminInfo(&c)

	// 查询App列表
	apps, _ := manager.GetAllAppList()
	appList := make([]interface{}, 0)
	for _, row := range apps {
		item := make(map[string]interface{})
		item["id"] = row.Id.Hex()
		item["app_name"] = row.App_name
		appList = append(appList, item)
	}

	data := make(map[string]interface{})
	data["loginAdminInfo"] = loginAdminInfo
	data["appList"] = appList
	data["env_desc"] = utils.GetEnvDesc()
	return c.Render(http.StatusOK, "add_premission.html", data)
}

// do add Premission
func DoAddPremission(c echo.Context) error {
	key := c.FormValue("key")
	if key == "" {
		return c.JSON(http.StatusOK, entity.Response{En: 402, Em: "请填写权限key"})
	}

	name := c.FormValue("name")
	if name == "" {
		return c.JSON(http.StatusOK, entity.Response{En: 402, Em: "请填写权限名称"})
	}

	appId := c.FormValue("app_id")
	if appId == "" {
		return c.JSON(http.StatusOK, entity.Response{En: 402, Em: "请选择权限App"})
	}

	// 判断当前app_id下是否存在这个key
	premission, err := manager.GetPremissionByAppIdKey(appId, key)
	if premission.Id.Hex() != "" {
		return c.JSON(http.StatusOK, entity.Response{En: 402, Em: "该权限已存在"})
	}

	task := model.Premission{
		Id:          bson.NewObjectId(),
		Key:         key,
		Name:        name,
		App_id:      appId,
		Adminid:     manager.GetCurrentAdminId(&c),
		Create_time: time.Now().Unix(),
		Update_time: time.Now().Unix(),
	}

	_, err = manager.SavePremission(task)
	if err != nil {
		return c.JSON(http.StatusOK, entity.Response{En: 402, Em: err.Error()})
	}

	return c.JSON(http.StatusOK, entity.Response{En: 200, Em: "成功"})
}

// UpdatePremission
func UpdatePremission(c echo.Context) error {
	loginAdminInfo := manager.GetLoginAdminInfo(&c)

	id := c.QueryParam("id")
	if id == "" {
		data := make(map[string]interface{})
		data["error_content"] = "😞请选择要修改的权限😞"
		data["loginAdminInfo"] = loginAdminInfo
		data["env_desc"] = utils.GetEnvDesc()
		return c.Render(http.StatusOK, "error.html", data)
	}

	// 查询任务信息
	premission, _ := manager.GetPremissionById(id)
	if premission.Id.Hex() == "" {
		data := make(map[string]interface{})
		data["error_content"] = "😞要修改的权限数据不存在😞"
		data["loginAdminInfo"] = loginAdminInfo
		data["env_desc"] = utils.GetEnvDesc()
		return c.Render(http.StatusOK, "error.html", data)
	}

	// 查询App列表
	apps, _ := manager.GetAllAppList()
	appList := make([]interface{}, 0)
	for _, row := range apps {
		item := make(map[string]interface{})
		item["id"] = row.Id.Hex()
		item["app_name"] = row.App_name
		appList = append(appList, item)
	}

	// 渲染结果到模板
	data := make(map[string]interface{})
	data["premissionInfo"] = formatPremission(premission)
	data["appList"] = appList
	data["loginAdminInfo"] = loginAdminInfo
	data["env_desc"] = utils.GetEnvDesc()
	return c.Render(http.StatusOK, "update_premission.html", data)
}

// DoUpdatePremission
func DoUpdatePremission(c echo.Context) error {
	id := c.FormValue("id")
	if id == "" {
		return c.JSON(http.StatusOK, entity.Response{En: 402, Em: "请选择要修改的权限"})
	}

	key := c.FormValue("key")
	if key == "" {
		return c.JSON(http.StatusOK, entity.Response{En: 402, Em: "请填写权限Key"})
	}

	name := c.FormValue("name")
	if name == "" {
		return c.JSON(http.StatusOK, entity.Response{En: 402, Em: "请填写权限名称"})
	}

	appId := c.FormValue("app_id")
	if appId == "" {
		return c.JSON(http.StatusOK, entity.Response{En: 402, Em: "请选择权限App"})
	}

	// 检查权限Key是否重复
	exPremissionItem, _ := manager.GetPremissionByKey(key)
	if (exPremissionItem.Id.Hex() != "") && (exPremissionItem.Id.Hex() != id) {
		return c.JSON(http.StatusOK, entity.Response{En: 402, Em: "该权限Key已存在"})
	}

	premission := make(map[string]interface{})
	premission["key"] = key
	premission["name"] = name
	premission["app_id"] = appId
	premission["update_time"] = time.Now().Unix()

	_, err := manager.UpdatePremission(id, premission)
	if err != nil {
		return c.JSON(http.StatusOK, entity.Response{En: 402, Em: err.Error()})
	}

	return c.JSON(http.StatusOK, entity.Response{En: 200, Em: "成功"})
}

// DoDeletePremission
func DoDeletePremission(c echo.Context) error {
	dataid := c.FormValue("id")

	if dataid == "" {
		return c.JSON(http.StatusOK, entity.Response{En: 402, Em: "请选择要删除的权限"})
	}

	// 判断任务是否存在
	premission, err := manager.GetPremissionById(dataid)
	if err != nil {
		return c.JSON(http.StatusOK, entity.Response{En: 402, Em: "数据错误"})
	}
	if premission.Id.Hex() != dataid {
		return c.JSON(http.StatusOK, entity.Response{En: 402, Em: "数据错误"})
	}

	// 物理删除权限
	b, err := manager.DeletePremission(dataid)
	if b == false {
		return c.JSON(http.StatusOK, entity.Response{En: 402, Em: err.Error()})
	}

	return c.JSON(http.StatusOK, entity.Response{En: 200, Em: "成功"})
}

// DoDeletePremissionBatch
func DoDeletePremissionBatch(c echo.Context) error {
	dataids := c.FormValue("ids")

	if dataids == "" {
		return c.JSON(http.StatusOK, entity.Response{En: 402, Em: "请选择要删除的权限"})
	}

	dataidsArray := strings.Split(dataids, ",")

	for _, dataid := range dataidsArray {
		// 判断任务是否存在
		premission, err := manager.GetPremissionById(dataid)
		if err != nil {
			return c.JSON(http.StatusOK, entity.Response{En: 402, Em: "数据错误"})
		}
		if premission.Id.Hex() != dataid {
			return c.JSON(http.StatusOK, entity.Response{En: 402, Em: "数据错误"})
		}

		// 物理删除权限
		b, err := manager.DeletePremission(dataid)
		if b == false {
			return c.JSON(http.StatusOK, entity.Response{En: 402, Em: err.Error()})
		}
	}

	return c.JSON(http.StatusOK, entity.Response{En: 200, Em: "成功"})
}

// PremissionList
func PremissionList(c echo.Context) error {
	loginAdminInfo := manager.GetLoginAdminInfo(&c)

	id := c.QueryParam("id")
	key := c.QueryParam("key")
	name := c.QueryParam("name")

	skip, page := utils.GetSkipPage(utils.PageCount, c)

	// 查询模板列表
	count, _ := manager.GetPremissionCount(id, key, name)
	premissions, _ := manager.GetPremissionList(id, key, name, skip, utils.PageCount)

	var premissionList []map[string]interface{}
	for _, row := range premissions {
		item := formatPremission(row)
		premissionList = append(premissionList, item)
	}

	res := utils.Paginator(page, utils.PageCount, count)

	linkPrefix, query := getPremissionLinkPrefixQuery("/premissionList?", id, key, name)

	// 渲染结果到模板
	data := make(map[string]interface{})
	data["premissionList"] = premissionList
	data["paginator"] = res
	data["linkPrefix"] = linkPrefix
	data["total"] = count
	data["loginAdminInfo"] = loginAdminInfo
	data["query"] = query
	data["env_desc"] = utils.GetEnvDesc()
	return c.Render(http.StatusOK, "premission_list.html", data)
}

func formatPremission(row model.Premission) map[string]interface{} {
	item := make(map[string]interface{})

	// 取App名称
	appName := ""
	if row.App_id != "" {
		app, _, err := manager.GetAppById(row.App_id)
		if err == nil && app.Id.Hex() != "" {
			appName = app.App_name
		}
	}

	// 取创建人姓名
	admin, _, _ := manager.GetAdminById(row.Adminid)
	adminName := ""
	if admin.Id.Hex() != "" {
		adminName = admin.Name
	}

	item["id"] = row.Id.Hex()
	item["key"] = row.Key
	item["name"] = row.Name
	item["app_id"] = row.App_id
	item["app_name"] = appName
	item["adminid"] = row.Adminid
	item["admin_name"] = adminName
	item["create_date"] = time.Unix(row.Create_time, 0).Format("2006-01-02 15:04:05")
	item["update_date"] = time.Unix(row.Update_time, 0).Format("2006-01-02 15:04:05")
	return item
}

func getPremissionLinkPrefixQuery(linkPrefix string, id string, key string, name string) (string, map[string]interface{}) {
	query := make(map[string]interface{})
	if id != "" {
		query["id"] = id
		linkPrefix += fmt.Sprintf("id=%s&", id)
	}
	if key != "" {
		query["key"] = key
		linkPrefix += fmt.Sprintf("key=%s&", key)
	}

	if name != "" {
		query["name"] = name
		linkPrefix += fmt.Sprintf("name=%s&", name)
	}

	return linkPrefix, query
}
